using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using BEPUphysics;
using Asplode.Renderer;
using Asplode.Events;
using BEPUphysics.Entities;
using Asplode.Physics;
using Asplode.GameWorld;

namespace Asplode
{
    public class Game : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        public AsplodeMap Map;
        private AsplodeRenderer Renderer;

        public EventDispatcher EventDispatcher = new EventDispatcher();

        public float camRotation;

        float aspectRatio;

        public Console console;

        public Space physics;

        public InputManager input;

        GameWorld.GameWorld GameWorld;

        public Game()
        {
            graphics = new GraphicsDeviceManager(this);

            input = new InputManager(this);

            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
            graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;
            int width = GraphicsDevice.Viewport.Width;
            int depth = GraphicsDevice.Viewport.Height;

            Map = new AsplodeMap(graphics.GraphicsDevice);
            Map.CameraPosition = new Vector3(0, 30, -30);

            Map.width = width;
            Map.depth = depth;

            Renderer = new AsplodeRenderer(this);
            var AsplodeRendererEventHandler = new AsplodeRendererEventHandler(Renderer);

            GameWorld = new GameWorld.GameWorld(EventDispatcher);
            var GameWorldEventHandler = new GameWorldEventHandler(GameWorld);

            physics = new Space();
            physics.simulationSettings.motionUpdate.gravity = new Vector3(0, -9.81f, 0);
            var PhysicsEventHandler = new PhysicsEventHandler(physics);
            
            EventDispatcher.addAllHandlers(AsplodeRendererEventHandler);
            EventDispatcher.addAllHandlers(GameWorldEventHandler);
            EventDispatcher.addAllHandlers(PhysicsEventHandler);

            base.Initialize();
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            Map.LoadContent(Content);

            console = new Console(Content, spriteBatch);

            console.Print("click to fire");
            
            EventDispatcher.Handle<GameWorld.GameWorld_InitializeGameEvent>(
                new GameWorld.GameWorld_InitializeGameEvent());
        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            if (Keyboard.GetState().IsKeyDown(Keys.I))
            {
                EventDispatcher.Handle<GameWorld.GameWorld_InitializeGameEvent>(
                new GameWorld.GameWorld_InitializeGameEvent());
            }
            input.Update(gameTime);
            physics.update(gameTime);
            GameWorld.Update(gameTime);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            
            //Map.Draw(GraphicsDevice,camRotation);

            GraphicsDevice.RenderState.DepthBufferEnable = true;
            // Draw everything in the Components collection.
            // base.Draw(gameTime);
            GraphicsDevice.RenderState.DepthBufferEnable = true;
            Renderer.Draw();


            spriteBatch.Begin();
            console.Draw();
            spriteBatch.End();

            GraphicsDevice.RenderState.DepthBufferEnable = true;
        }
    }
}